/* $Header: p_det.c,v 2.2 01/10/02 10:27:48 przybyls Exp $ */

/***********************************************************************/
/*                                                                     */
/*                  Copyright Hewlett-Packard Co. 1991                 */
/*                                                                     */
/***********************************************************************/

/***********************************************************************/
/* MODULE NAME:  Detector Control and Display                          */
/* ============                                                        */
/*                                                                     */
/* Author: wikfors                                                     */
/*                                                                     */
/* MODULE PURPOSE: Provide for the control and display of det flows    */
/*                                                                     */
/*                                                                     */
/*                                                                     */
/*                                                                     */
/***********************************************************************/


/*****************************/
/*   GLOBAL INCLUDE FILES    */
/*****************************/


#include <typedefs.h>
#include <p_wkfile.h>
#include <error.h>
#include <exception.h>
#include <err_handler.h>
#include <p_status.h>
#include <p_filter.h>
#include <detector.h>
#include <list_mgmt.h>
#include <keyboard.h>
#include <p_ui.h>
#include <det_ui.h>

/*****************************/
/*   LOCAL INCLUDE FILES     */
/*****************************/

#include "proto.h"

/*****************************/
/*   GLOBAL VARIABLES        */
/*****************************/


/*****************************/
/*   EXTERNAL VARIABLES      */
/*****************************/


/*****************************/
/*   LOCAL DEFINES           */
/*****************************/

#define DET_READY_TICS 60  /* 6 Sec @ 10 Hz */

/*****************************/
/*   STATIC VARIABLES        */
/*****************************/


/*****************************/
/*   IMPLEMENT SECTION       */
/*****************************/
/**begin_proto**/

#pragma SECTION PROG=rom3

/**end_proto**/


/***********************************************************************/
/* MACRO:    DetermineMakeupFlow                                       */
/* ======                                                              */
/*                                                                     */
/* PURPOSE:  determine the total amount (mL/min) of column flow        */
/*                                                                     */
/* RETURNED VALUE: column flow (mL/min) with IU scaling                */
/*                                                                     */
/* LIMITATIONS:  Column iu scaling must be >= 16384                    */
/*                                                                     */
/***********************************************************************/
/**begin_proto**/

void DetermineMakeupFlow ( pDETECTOR_STATUS status )

/**end_proto**/
{

   U_INT32 column_flow;

   if (( status->Wkfile->Constant_Total_Makeup == ON ) && ( status->Has_Column ))
   {

       column_flow =  FindTotalOutletFlow ( status->Position, status->IU_Scaling );

       if ( column_flow >  status->Wkfile->Desired_Total_Makeup_Flow )
       {
           status->Gas_3.Desired_Flow = 0;
           /* Revisit       this is an error condition */
           /* GoNotReady( column_flow_exceeds_detector_setpt ); */
       }
       else
       {
           status->Gas_3.Desired_Flow = status->Wkfile->Desired_Total_Makeup_Flow - column_flow;
       }
   }
   else  /* detector makeup gas flow is not in constant mode */
   {
       status->Gas_3.Desired_Flow = status->Wkfile->Gas_3.Desired_Flow;
   }

}



void RangeCheckDetGasPres( U_INT16 *pres, pDETECTOR_STATUS status, U_INT8 gas_num )
{
   U_INT16   range;
   BIT8      *capped;

   switch ( gas_num )
   {
       case 1:  capped = &status->Ready.Fuel_Capped;
                range =   status->Tcomp_Tables->Fuel.Pres_Sensor.Parms.Range;
                break;

       case 2:  capped = &status->Ready.Util_Capped;
                range =   status->Tcomp_Tables->Util.Pres_Sensor.Parms.Range;
                break;

       default:  /* for Lint */
       case 3:  capped = &status->Ready.Mug_Capped;
                range =   status->Tcomp_Tables->Mug.Pres_Sensor.Parms.Range;
                break;
   }

   if ( *pres > range )
   {
        *pres = range;
        *capped = TRUE;
   }
   else
   {
        *capped = FALSE;
   }


}


/***********************************************************************/
/* FUNCTION:                                                           */
/* ========                                                            */
/*                                                                     */
/* PURPOSE:                                                            */
/*                                                                     */
/* RETURNED VALUE:                                                     */
/*                                                                     */
/* GLOBALS USED:                                                       */
/*                                                                     */
/***********************************************************************/

/**begin_proto**/

void DoDetGasSetpt ( pDET_GAS gas_status, pDETECTOR_STATUS status, U_INT8 gas_num )

/**end_proto**/
{

     U_INT32 desired_flow;
     U_INT16 pres;
     U_INT16 setpt;

     if ( !gas_status->Comp_Tables_Ok ) return;

     if ( gas_status->FRIT_MAX_FLOW != 0 )
     {
          FilterValue( gas_status->Filtered_Flow_Setpt, gas_status->Desired_Flow );

          desired_flow = gas_status->Filtered_Flow_Setpt;

          if ( desired_flow != 0 )
          {

              pres = FritFlowToPres( desired_flow,
                                     &gas_status->Tcomp_Tables->Frit,
                                     status->Tcomp_Tables->Thermistor.Module_Temperature,
                                     Atmospheric_Pressure.Dcm2_160 );
          }
          else
          {
              pres = 0;
          }

          gas_status->Pres_Setpt = pres;
     }
     else
     {
          Filter16Bits( &gas_status->Pres_Setpt, gas_status->Desired_Pres, AUX_PRES_FILTER_RATE );
          Filter32Bits( &gas_status->Delayed_Det_Pres_Setpt, gas_status->Pres_Setpt, AUX_PRES_DELAY );
          pres = gas_status->Pres_Setpt;
     }


     if ( pres != 0 )
     {
          RangeCheckDetGasPres( &pres, status, gas_num );

          setpt = PresToVolts( pres,
                               &gas_status->Tcomp_Tables->Pres_Sensor,
                               status->Tcomp_Tables->Thermistor.Module_Temperature,
                               gas_status->Calib.Offset,
                               gas_status->Calib.Gain  );
     }
     else
     {
          setpt = 0 ;
     }

     gas_status->Adc_Setpt = setpt;


}

/**begin_proto**/

void DoDetGasActual ( pDET_GAS gas_status, pDETECTOR_STATUS status )

/**end_proto**/
{

     U_INT32 flow;
     U_INT16 pres;

     if ( !gas_status->Comp_Tables_Ok ) return;


     pres = VoltsToPres( gas_status->Adc_Actual,
                         &gas_status->Tcomp_Tables->Pres_Sensor,
                         status->Tcomp_Tables->Thermistor.Module_Temperature,
                         gas_status->Calib.Offset, gas_status->Calib.Gain );

     if (gas_status->FRIT_MAX_FLOW != 0 )
     {
          gas_status->Current_Pres = pres;

          flow = FritPresToFlow( pres,
                                 &gas_status->Tcomp_Tables->Frit,
                                 status->Tcomp_Tables->Thermistor.Module_Temperature,
                                 Atmospheric_Pressure.Dcm2_160 );

          FilterValue( gas_status->Filtered_Current_Flow, flow );
     }
     else
     {
          Filter16Bits( &gas_status->Current_Pres, pres, AUX_PRES_FILTER_RATE );
     }
}

/***********************************************************************/
/* FUNCTION:  DoDetGases                                               */
/* ========                                                            */
/*                                                                     */
/* PURPOSE:  Calculate Adc setpts for det gasses from flow setpts      */
/*                                                                     */
/***********************************************************************/
/**begin_proto**/

void DoDetGases ( pDETECTOR_STATUS status )

/**end_proto**/
{

   if ( status->Gas_3.On_Off == ON )
   {
           if ( status->Gas_3.FRIT_MAX_FLOW != 0 )
           {
                status->Ready.Mug_Flow.Controlled  = TRUE;
                if ( status->Config->Type != EPC_OEM )
                {
                     DetermineMakeupFlow ( status );
                }
           }

           DoDetGasSetpt ( &status->Gas_3, status, 3 );
           status->Ready.Mug_Pres.Controlled  = TRUE;
   }
   else
   {
           status->Gas_3.Adc_Setpt = 0;
           status->Ready.Mug_Pres.Controlled  = FALSE;
           status->Ready.Mug_Flow.Controlled  = FALSE;
   }

   if (DetIsAnyUECDorLDID( status )) return ;

   if ( status->Gas_2.On_Off == ON )
   {
           DoDetGasSetpt ( &status->Gas_2, status, 2 );
           status->Ready.Util_Pres.Controlled  = TRUE;
           if ( status->Gas_2.FRIT_MAX_FLOW != 0 )
           {
                status->Ready.Util_Flow.Controlled  = TRUE;
           }

   }
   else
   {
           status->Gas_2.Adc_Setpt = 0;
           status->Ready.Util_Pres.Controlled  = FALSE;
           status->Ready.Util_Flow.Controlled  = FALSE;
   }

   if (DetIsTCDorAnyECD( status )) return ;

   if ( status->Gas_1.On_Off == ON )
   {
      DoDetGasSetpt ( &status->Gas_1, status, 1 );
      status->Ready.Fuel_Pres.Controlled  = TRUE;
      if ( status->Gas_1.FRIT_MAX_FLOW != 0 )
      {
           status->Ready.Fuel_Flow.Controlled  = TRUE;
      }
   }
   else
   {
      status->Gas_1.Adc_Setpt = 0;
      status->Ready.Fuel_Pres.Controlled  = FALSE;
      status->Ready.Fuel_Flow.Controlled  = FALSE;
   }
}

/***********************************************************************/
/* FUNCTION:  CalcDetFP                                                */
/* ========                                                            */
/*                                                                     */
/* PURPOSE:  Calculate actual flows and pressures based on adc rdgs    */
/*                                                                     */
/***********************************************************************/
/**begin_proto**/

void CalcDetGasFP ( pDETECTOR_STATUS status )

/**end_proto**/
{

   DoDetGasActual ( &status->Gas_3, status );

   if (DetIsAnyUECDorLDID( status )) return ;

   DoDetGasActual ( &status->Gas_2, status );

   if (DetIsTCDorAnyECD( status )) return ;

   DoDetGasActual ( &status->Gas_1, status );

}

/***********************************************************************/
/* FUNCTION:                                                           */
/* ========                                                            */
/*                                                                     */
/* PURPOSE:                                                            */
/*                                                                     */
/* RETURNED VALUE:                                                     */
/*                                                                     */
/* GLOBALS USED:                                                       */
/*                                                                     */
/***********************************************************************/
/**begin_proto**/

INT32 DetFlowReadyCheck( pDETECTOR_STATUS status, U_INT8 gas_channel  )

/**end_proto**/
{

    pDET_GAS   gas;
    pHERE_I_COME ready;
    ON_OFF     on_off;
    BIT8       change;
    BIT8       capped;

    switch ( gas_channel )
    {
       case 1:  gas    = &status->Gas_1;
                ready  = &status->Ready.Fuel_Flow;
                on_off = status->Wkfile->Gas_1.On_Off;
                change = status->Ready.Fuel_Setpt_Change || status->Ready.Setpt_Change;
                capped = status->Ready.Fuel_Capped;
                break;
       case 2:  gas    = &status->Gas_2;
                ready  = &status->Ready.Util_Flow;
                on_off = status->Wkfile->Gas_2.On_Off;
                change = status->Ready.Util_Setpt_Change || status->Ready.Setpt_Change;
                capped = status->Ready.Util_Capped;
                break;
       case 3:  gas    = &status->Gas_3;
                ready  = &status->Ready.Mug_Flow;
                on_off = status->Wkfile->Gas_3.On_Off;
                change = status->Ready.Mug_Setpt_Change || status->Ready.Setpt_Change;
                capped = status->Ready.Mug_Capped;
                break;
       default:  return 1; /* not ready for any non real gasses */
    }

    ready->Setpt  = gas->Filtered_Flow_Setpt;
    ready->Actual = gas->Filtered_Current_Flow;

    ready->Difference = ( gas->Filtered_Current_Flow - gas->Filtered_Flow_Setpt );

    ready->Bound =  status->IU_Scaling;  /* 1 mL/min */

    ready->In_Bounds = (ready->Difference < 0) ?
                                    ready->Difference > -ready->Bound :
                                    ready->Difference <  ready->Bound ;

    EvalPneuReady( ready,
                   ( CountDetChangeRequests( status, gas_channel ) != 0 ) || change || capped,
                   gas->Shutdown,
                   ready->In_Bounds,
                   ready->Controlled && ( on_off == ON ),
                   FALSE,
                   EVENT_TIMEOUT / READY_EVAL_PERIOD,
                   DET_READY_TICS );


    return ready->Reported_Ready == FALSE;

}

/**begin_proto**/

INT32 DetPresReadyCheck( pDETECTOR_STATUS status, U_INT8 gas_channel  )

/**end_proto**/
{

    pDET_GAS   gas;
    pHERE_I_COME ready;
    ON_OFF     on_off;
    U_INT16    Dcm2_Per_IU;
    BIT8       change;
    BIT8       required;
    BIT8       capped;

    switch ( gas_channel )
    {
       case 1:  gas    = &status->Gas_1;
                ready  = &status->Ready.Fuel_Pres;
                on_off = status->Wkfile->Gas_1.On_Off;
                Dcm2_Per_IU = status->Gas_1.Dcm2_Per_IU;
                change = (
                           ( status->Gas_1.FRIT_MAX_FLOW != 0 ) ? status->Ready.Fuel_Setpt_Change:
                                                                  status->Ready.Pres1_Setpt_Change
                         )
                         ||
                         status->Ready.Setpt_Change;
                capped = status->Ready.Fuel_Capped;
                break;
       case 2:  gas    = &status->Gas_2;
                ready  = &status->Ready.Util_Pres;
                on_off = status->Wkfile->Gas_2.On_Off;
                Dcm2_Per_IU = status->Gas_2.Dcm2_Per_IU;
                change = (
                           ( status->Gas_2.FRIT_MAX_FLOW != 0 ) ? status->Ready.Util_Setpt_Change:
                                                                  status->Ready.Pres2_Setpt_Change
                         )
                         ||
                         status->Ready.Setpt_Change;
                capped = status->Ready.Util_Capped;
                break;
       case 3:  gas    = &status->Gas_3;
                ready  = &status->Ready.Mug_Pres;
                on_off = status->Wkfile->Gas_3.On_Off;
                Dcm2_Per_IU = status->Gas_3.Dcm2_Per_IU;
                change = (
                           ( status->Gas_3.FRIT_MAX_FLOW != 0 ) ? status->Ready.Mug_Setpt_Change:
                                                                  status->Ready.Pres3_Setpt_Change
                         )
                         ||
                         status->Ready.Setpt_Change;
                capped = status->Ready.Mug_Capped;
                break;
       default:  return 1; /* not ready for any non real gasses */
    }

    required = IsDetGasRequired( DET_POSITION( status )  , gas_channel );

    ready->Setpt  = gas->Delayed_Det_Pres_Setpt;
    ready->Actual = gas->Current_Pres;

    ready->Difference = ( gas->Current_Pres - gas->Pres_Setpt );

    switch ( Dcm2_Per_IU )
    {
    case  80: ready->Bound =  (  3447 /  80 );  /* .05 PSI = 3447.378 Dynes/cm*cm */
              break;
    case 160: ready->Bound =  (  6894 / 160 );  /* .1  PSI = 6894.757 Dynes/cm*cm */
              break;
    case 320: ready->Bound =  ( 34473 / 320 );  /* .5  PSI = 34473.85 Dynes/cm*cm */
              break;
              /* default case to keep lint happy */
    default:  ready->Bound =  (  6894 / 160 );  /* .1  PSI = 6894.757 Dynes/cm*cm */
    }

    ready->In_Bounds = (ready->Difference < 0) ?
                                    ready->Difference > -ready->Bound :
                                    ready->Difference <  ready->Bound ;

    EvalPneuReady( ready,
                   ( CountDetChangeRequests( status, gas_channel ) != 0 ) ||
                     change ||
                     ( required && (on_off == OFF ) ||
                     capped ),
                   gas->Shutdown,
                   ready->In_Bounds,
                   ( ready->Controlled && ( on_off == ON ) ) || required,
                   FALSE,
                   EVENT_TIMEOUT / READY_EVAL_PERIOD,
                   DET_READY_TICS );


    return ready->Reported_Ready == FALSE;

}

/***********************************************************************/
/* FUNCTION:                                                           */
/* ========                                                            */
/*                                                                     */
/* PURPOSE:                                                            */
/*                                                                     */
/* RETURNED VALUE:                                                     */
/*                                                                     */
/* GLOBALS USED:                                                       */
/*                                                                     */
/***********************************************************************/

static INT32 GetDetGasExcptnParm( pDETECTOR_STATUS status , BIT8 gas  )
{
   if ( GetOEMGasStatus(status,gas) == PRES )
   {
      return GetDetectorPresActual(  status,  gas ) ;
   }
   else
   {
      return ConvertFlowIuToDisplay( (gas == 1)? status->Gas_1.Filtered_Current_Flow:
                                     (gas == 2)? status->Gas_2.Filtered_Current_Flow:
                                                 status->Gas_3.Filtered_Current_Flow , status->IU_Scaling );
   }
}

/**begin_proto**/

void CheckEpcDetectorReadiness( pDETECTOR_STATUS status )

/**end_proto**/
{

    INT32 gas_1_readiness;
    INT32 gas_2_readiness;
    INT32 gas_3_readiness;

    if ( !status->Config->Functional )
    {
       gas_1_readiness = 0; /* always ready when off */
       gas_2_readiness = 0;
       gas_3_readiness = 0;
    }
    else
    {
       gas_3_readiness = DetPresReadyCheck( status, 3);
       (void)            DetFlowReadyCheck( status, 3);

       if (DetIsAnyUECDorLDID( status ) )
       {
          gas_1_readiness = 0;
          gas_2_readiness = 0;
       }
       else
       {
          gas_2_readiness = DetPresReadyCheck( status, 2);
          (void)            DetFlowReadyCheck( status, 2);

          if (DetIsTCDorAnyECD( status ))
          {
             gas_1_readiness = 0;
          }
          else
          {
             gas_1_readiness = DetPresReadyCheck( status, 1);
             (void)            DetFlowReadyCheck( status, 1);
          }
       }
    }

    status->Ready.Fuel_Setpt_Change = FALSE;
    status->Ready.Util_Setpt_Change = FALSE;
    status->Ready.Mug_Setpt_Change  = FALSE;
    status->Ready.Pres1_Setpt_Change = FALSE;
    status->Ready.Pres2_Setpt_Change = FALSE;
    status->Ready.Pres3_Setpt_Change  = FALSE;
    status->Ready.Setpt_Change      = FALSE;

    if ( status->Position == FRNT_DET )
    {
        if ( gas_1_readiness )
        {
           SetNewException( FRNT_DET_GAS_1_FLOW, GetDetGasExcptnParm( status , 1 ), 0 );
        }
        else
        {
           ClearNewException ( FRNT_DET_GAS_1_FLOW );
        }

        if ( gas_2_readiness )
        {
           SetNewException( FRNT_DET_GAS_2_FLOW, GetDetGasExcptnParm( status , 2 ), 0 );
        }
        else
        {
           ClearNewException ( FRNT_DET_GAS_2_FLOW );
        }

        if ( gas_3_readiness )
        {
           SetNewException( FRNT_DET_GAS_3_FLOW, GetDetGasExcptnParm( status , 3 ), 0 );
        }
        else
        {
           ClearNewException ( FRNT_DET_GAS_3_FLOW );
        }

    }
    else
    {
        if ( gas_1_readiness )
        {
           SetNewException( BACK_DET_GAS_1_FLOW,  GetDetGasExcptnParm( status , 1 ), 0 );
        }
        else
        {
           ClearNewException ( BACK_DET_GAS_1_FLOW );
        }

        if ( gas_2_readiness )
        {
           SetNewException( BACK_DET_GAS_2_FLOW, GetDetGasExcptnParm( status , 2 ), 0 );
        }
        else
        {
           ClearNewException ( BACK_DET_GAS_2_FLOW );
        }

        if ( gas_3_readiness )
        {
           SetNewException( BACK_DET_GAS_3_FLOW, GetDetGasExcptnParm( status , 3 ), 0 );
        }
        else
        {
           ClearNewException ( BACK_DET_GAS_3_FLOW );
        }

    }


}

/***********************************************************************/
/* FUNCTION:                                                           */
/* ========                                                            */
/*                                                                     */
/* PURPOSE:                                                            */
/*                                                                     */
/* RETURNED VALUE:                                                     */
/*                                                                     */
/* GLOBALS USED:                                                       */
/*                                                                     */
/***********************************************************************/
/**begin_proto**/

void CheckManualDetectorReadiness( pDETECTOR_STATUS status )

/**end_proto**/
{


    INT32 gas_1_readiness;
    INT32 gas_2_readiness;
    INT32 gas_3_readiness;

    if ( !status->Config->Functional )
    {
             gas_1_readiness = 0; /* always ready when off */
             gas_2_readiness = 0;
             gas_3_readiness = 0;
    }
    else
    {
        if (( status->Config->Type == MAN_TCD ) || (status->Config->Type == MAN_ECD ))
        {
             gas_1_readiness = 0;
        }
        else
        {
             gas_1_readiness = ( status->Gas_1.On_Off == OFF ) && IsDetGasRequired( DET_POSITION( status ), 1 );
        }

        gas_2_readiness = ( status->Gas_2.On_Off == OFF ) && IsDetGasRequired( DET_POSITION( status ), 2 );
        gas_3_readiness = ( status->Gas_3.On_Off == OFF ) && IsDetGasRequired( DET_POSITION( status ), 3 );
    }


    if ( status->Position == FRNT_DET )
    {
        if ( gas_1_readiness ) SetNewException   ( FRNT_DET_GAS_1_OFF, 0, 0 );
        else                   ClearNewException ( FRNT_DET_GAS_1_OFF );

        if ( gas_2_readiness ) SetNewException   ( FRNT_DET_GAS_2_OFF, 0, 0 );
        else                   ClearNewException ( FRNT_DET_GAS_2_OFF );

        if ( gas_3_readiness ) SetNewException   ( FRNT_DET_GAS_3_OFF, 0, 0 );
        else                   ClearNewException ( FRNT_DET_GAS_3_OFF );

    }
    else
    {
        if ( gas_1_readiness ) SetNewException   ( BACK_DET_GAS_1_OFF, 0, 0 );
        else                   ClearNewException ( BACK_DET_GAS_1_OFF );

        if ( gas_2_readiness ) SetNewException   ( BACK_DET_GAS_2_OFF, 0, 0 );
        else                   ClearNewException ( BACK_DET_GAS_2_OFF );

        if ( gas_3_readiness ) SetNewException   ( BACK_DET_GAS_3_OFF, 0, 0 );
        else                   ClearNewException ( BACK_DET_GAS_3_OFF );

    }
}

/**begin_proto**/

void CheckDetectorReadiness( pDETECTOR_STATUS status )

/**end_proto**/
{
    if ( EpcDetector ( status ) )
    {
         CheckEpcDetectorReadiness( status );

         LowTCDRefCheck(status);

         if ( status->Position == FRNT_DET )
         {
             ClearNewException ( FRNT_DET_GAS_1_OFF );
             ClearNewException ( FRNT_DET_GAS_2_OFF );
             ClearNewException ( FRNT_DET_GAS_3_OFF );
         }
         else
         {
             ClearNewException ( BACK_DET_GAS_1_OFF );
             ClearNewException ( BACK_DET_GAS_2_OFF );
             ClearNewException ( BACK_DET_GAS_3_OFF );
         }

    }
    else if ( ManDetector ( status ) )
    {
         CheckManualDetectorReadiness( status );

         if ( status->Position == FRNT_DET )
         {
             ClearNewException ( FRNT_DET_GAS_1_FLOW );
             ClearNewException ( FRNT_DET_GAS_2_FLOW );
             ClearNewException ( FRNT_DET_GAS_3_FLOW );
         }
         else
         {
             ClearNewException ( BACK_DET_GAS_1_FLOW );
             ClearNewException ( BACK_DET_GAS_2_FLOW );
             ClearNewException ( BACK_DET_GAS_3_FLOW );
         }

    }
    else
    {
         if ( status->Position == FRNT_DET )
         {
         /* some non-functional or non-existant detector */
             ClearNewException ( FRNT_DET_GAS_1_FLOW );
             ClearNewException ( FRNT_DET_GAS_2_FLOW );
             ClearNewException ( FRNT_DET_GAS_3_FLOW );

             ClearNewException ( FRNT_DET_GAS_1_OFF );
             ClearNewException ( FRNT_DET_GAS_2_OFF );
             ClearNewException ( FRNT_DET_GAS_3_OFF );
         }
         else
         {
             ClearNewException ( BACK_DET_GAS_1_FLOW );
             ClearNewException ( BACK_DET_GAS_2_FLOW );
             ClearNewException ( BACK_DET_GAS_3_FLOW );

             ClearNewException ( BACK_DET_GAS_1_OFF );
             ClearNewException ( BACK_DET_GAS_2_OFF );
             ClearNewException ( BACK_DET_GAS_3_OFF );
         }
    }


}

/**begin_proto**/

#pragma SECTION UNDO

/**end_proto**/
